/*
 * INodo.h
 *
 *  Created on: 03/04/2010
 *      Author: administrador
 */

#ifndef INODO_H_
#define INODO_H_

#define Comun '0'
#define Raiz '1'

#include <vector>
#include "Elemento.h"
#include "Excepciones.h"
#include "Serializable.h"
#include "INodo.h"


class INodo: public Serializable {

protected:

	/* Indica si es nodo RAIZ o nodo COMUN */
	char tipo;

	/* Identificador del nodo */
	int id;

	/* Nivel del nodo en el arbol */
	int nivel;

	/* Para Nodos Hoja = cantidad actual de elementos
	 * Para Nodos Indice = cantidad actual de claves de elementos */
	int cantidadElementos;

	/* Tamaño en bytes actual del nodo (se utiliza para OverFlow y UnderFlow) */
	int tamanioActual;

	static int factorCargaOverflow;

	static int factorCargaUnderflow;

	int getTamanioElementosControlNodo();


public:
	virtual int verificarSeparador() = 0;

	INodo(char tipo = Comun);

	INodo(int idNodo, char tipo = Comun);

	virtual ~INodo();

	int getId();

	int getNivel();

	int getCantidadElementos();

	int getTamanioActual();

	virtual void setCantidadElementos(int cantidad);

	void setTamanioActual(int tamanio);

	virtual void partirNodoEnOverflow(int &claveAPromover, INodo* nodoNuevo) = 0;

	/* Se intenta balancear ambos nodos intentando que sus tamaños sean lo mas parecido posibles */
	virtual bool balancearNodoEnUnderflow(int clavePadre,INodo* nodoHermano) = 0;

	/* Se fusionan ambos nodos en el que tenga elementos de menor clave */
	virtual bool fusionarNodoEnUnderflow(int clavePadre,INodo* nodoHermano) = 0;

	virtual int getClaveAPromover() = 0;

	virtual bool insertarElemento(Elemento* elemento) = 0;

	virtual bool quitarElemento(int clave) = 0;

	virtual bool modificarElemento(int clave, string* nuevoValor) = 0;

	virtual void setId(int idNodo);

	/* Retorna el elemento que contenga la clave pasada por parametro.
	 * Si el elemento no existe, retorna el elemento con clave inmediatamente siguiente.
	 * Si la clave es mayor a la del ultimo elemento, retorna la excepecion Elemento Inexistente */
	virtual Elemento* buscarElemento(int clave) = 0;

	virtual void printNodo(int cantidadNiveles) = 0;

	static void setTamanioNodo(int tamanio);
};

#endif /* INODO_H_ */
